package com.ruoyi.quartz.task;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.core.domain.entity.SysTaskCycle;
import com.ruoyi.common.core.domain.entity.SysTaskPlan;
import com.ruoyi.common.core.domain.entity.SysTaskPlanDetail;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.quartz.domain.SysJob;
import com.ruoyi.quartz.util.CronUtil;
import com.ruoyi.quartz.util.ScheduleUtils;
import com.ruoyi.system.domain.SysUserPost;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.SysTaskCycleService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;

/**
 * 定时任务调度测试
 *
 * @author ruoyi
 */
@Slf4j
@Component("ryTask")
public class RyTask {
    public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i) {
        System.out.println(StringUtils.format("执行多参方法： 字符串类型{}，布尔类型{}，长整型{}，浮点型{}，整形{}", s, b, l, d, i));
    }

    public void ryParams(String params) {
        System.out.println("执行有参方法：" + params);
    }

    public void ryNoParams() {
        System.out.println("执行无参方法");
    }


    @Autowired
    private Scheduler scheduler;

    @Resource
    SysUserPostMapper sysUserPostMapper;

    @Resource
    SysTaskPlanMapper sysTaskPlanMapper;

    @Resource
    SysTaskPlanDetailMapper sysTaskPlanDetailMapper;

    @Resource
    SysTaskCycleService sysTaskCycleService;

    private final static String name = "巡河计划";


    /**
     * 每日0点执行
     */
    public void day() {
        log.info("每日定时开始创建任务计划");

        List<SysTaskCycle> sysTaskCycleList = sysTaskCycleService.list(Wrappers.<SysTaskCycle>lambdaQuery()
                .eq(SysTaskCycle::getStatus, 1)
                .eq(SysTaskCycle::getCycleId, 1)
        );

        if (CollUtil.isNotEmpty(sysTaskCycleList)) {
            DateTime nowDate = DateUtil.date();
            DateTime startTime = DateUtil.beginOfDay(nowDate);
            DateTime endTime = DateUtil.endOfDay(nowDate);
            String date = DateUtil.format(nowDate, DatePattern.CHINESE_DATE_PATTERN);

            for (SysTaskCycle sysTaskCycle : sysTaskCycleList) {

                Integer frequency = sysTaskCycle.getFrequency();
                List<SysUserPost> sysUserPosts = sysUserPostMapper.selectList(Wrappers.<SysUserPost>lambdaQuery()
                        .eq(SysUserPost::getPostId, sysTaskCycle.getPostId())
                );

                SysTaskPlan sysTaskPlan = null;
                for (Integer i = 0; i < frequency; i++) {
                    sysTaskPlan = SysTaskPlan.builder()
                            .taskName(date + name)
                            .remarks(CharSequenceUtil.EMPTY)
                            .cycleId(1L)
                            .finish(0)
                            .creatorId(1L)
                            .publishTime(nowDate)
                            .createTime(nowDate)
                            .startTime(startTime)
                            .endTime(endTime)
                            .state(1)
                            .type(1)
                            .taskType(1)
                            .flowpath(2)
                            .build();
                    sysTaskPlanMapper.insert(sysTaskPlan);

                    SysTaskPlanDetail sysTaskPlanDetail = null;
                    for (SysUserPost sysUserPost : sysUserPosts) {
                        sysTaskPlanDetail = new SysTaskPlanDetail();
                        sysTaskPlanDetail.setUserId(sysUserPost.getUserId());
                        sysTaskPlanDetail.setPlanId(sysTaskPlan.getId());
                        sysTaskPlanDetail.setFinish(0);
                        sysTaskPlanDetail.setState(1);
                        sysTaskPlanDetailMapper.insert(sysTaskPlanDetail);
                    }
                    extracted(sysTaskPlan);
                }
            }
        }
        log.info("每日定时结束创建任务计划");
    }


    /**
     * 每周0点执行
     */
    public void week() {
        log.info("每周定时开始创建任务计划");

        List<SysTaskCycle> sysTaskCycleList = sysTaskCycleService.list(Wrappers.<SysTaskCycle>lambdaQuery()
                .eq(SysTaskCycle::getStatus, 1)
                .eq(SysTaskCycle::getCycleId, 2)
        );

        if (CollUtil.isNotEmpty(sysTaskCycleList)) {
            DateTime nowDate = DateUtil.date();
            DateTime startTime = DateUtil.beginOfDay(nowDate);
            DateTime endTime = DateUtil.endOfWeek(nowDate);
            String date = DateUtil.format(nowDate, DatePattern.CHINESE_DATE_PATTERN).substring(0, 8);

            for (SysTaskCycle sysTaskCycle : sysTaskCycleList) {

                Integer frequency = sysTaskCycle.getFrequency();
                List<SysUserPost> sysUserPosts = sysUserPostMapper.selectList(Wrappers.<SysUserPost>lambdaQuery()
                        .eq(SysUserPost::getPostId, sysTaskCycle.getPostId())
                );

                int weekInMonth = DateUtil.beginOfDay(nowDate).dayOfWeekInMonth();
                SysTaskPlan sysTaskPlan = null;
                for (Integer i = 0; i < frequency; i++) {
                    sysTaskPlan = SysTaskPlan.builder()
                            .taskName(date + "第" + weekInMonth + "周" + name)
                            .remarks(CharSequenceUtil.EMPTY)
                            .cycleId(2L)
                            .finish(0)
                            .creatorId(1L)
                            .publishTime(nowDate)
                            .createTime(nowDate)
                            .startTime(startTime)
                            .endTime(endTime)
                            .state(1)
                            .type(1)
                            .taskType(1)
                            .flowpath(2)
                            .build();
                    sysTaskPlanMapper.insert(sysTaskPlan);

                    SysTaskPlanDetail sysTaskPlanDetail = null;
                    for (SysUserPost sysUserPost : sysUserPosts) {
                        sysTaskPlanDetail = new SysTaskPlanDetail();
                        sysTaskPlanDetail.setUserId(sysUserPost.getUserId());
                        sysTaskPlanDetail.setPlanId(sysTaskPlan.getId());
                        sysTaskPlanDetail.setFinish(0);
                        sysTaskPlanDetail.setState(1);
                        sysTaskPlanDetailMapper.insert(sysTaskPlanDetail);
                    }
                    extracted(sysTaskPlan);
                }
            }
        }
        log.info("每周定时结束创建任务计划");
    }


    /**
     * 每月0点执行
     */
    public void month() {
        log.info("每月定时开始创建任务计划");

        List<SysTaskCycle> sysTaskCycleList = sysTaskCycleService.list(Wrappers.<SysTaskCycle>lambdaQuery()
                .eq(SysTaskCycle::getStatus, 1)
                .eq(SysTaskCycle::getCycleId, 3)
        );
        if (CollUtil.isNotEmpty(sysTaskCycleList)) {
            DateTime nowDate = DateUtil.date();
            DateTime startTime = DateUtil.beginOfDay(nowDate);
            DateTime endTime = DateUtil.endOfMonth(nowDate);
            String date = DateUtil.format(nowDate, DatePattern.CHINESE_DATE_PATTERN).substring(0, 8);

            for (SysTaskCycle sysTaskCycle : sysTaskCycleList) {

                Integer frequency = sysTaskCycle.getFrequency();
                List<SysUserPost> sysUserPosts = sysUserPostMapper.selectList(Wrappers.<SysUserPost>lambdaQuery()
                        .eq(SysUserPost::getPostId, sysTaskCycle.getPostId())
                );

                SysTaskPlan sysTaskPlan = null;
                for (Integer i = 0; i < frequency; i++) {
                    sysTaskPlan = SysTaskPlan.builder()
                            .taskName(date + name)
                            .remarks(CharSequenceUtil.EMPTY)
                            .cycleId(3L)
                            .finish(0)
                            .creatorId(1L)
                            .publishTime(nowDate)
                            .createTime(nowDate)
                            .startTime(startTime)
                            .endTime(endTime)
                            .state(1)
                            .type(1)
                            .taskType(1)
                            .flowpath(2)
                            .build();
                    sysTaskPlanMapper.insert(sysTaskPlan);
                    SysTaskPlanDetail sysTaskPlanDetail = null;

                    for (SysUserPost sysUserPost : sysUserPosts) {
                        sysTaskPlanDetail = new SysTaskPlanDetail();
                        sysTaskPlanDetail.setUserId(sysUserPost.getUserId());
                        sysTaskPlanDetail.setPlanId(sysTaskPlan.getId());
                        sysTaskPlanDetail.setFinish(0);
                        sysTaskPlanDetail.setState(1);
                        sysTaskPlanDetailMapper.insert(sysTaskPlanDetail);
                    }
                    extracted(sysTaskPlan);
                }
            }
        }
        log.info("每月定时结束创建任务计划");
    }

    /**
     * 每个季度0点执行
     */
    public void quarter() {
        log.info("季度定时开始创建任务计划");

        List<SysTaskCycle> sysTaskCycleList = sysTaskCycleService.list(Wrappers.<SysTaskCycle>lambdaQuery()
                .eq(SysTaskCycle::getStatus, 1)
                .eq(SysTaskCycle::getCycleId, 4)
        );
        if (CollUtil.isNotEmpty(sysTaskCycleList)) {

            DateTime nowDate = DateUtil.date();
            DateTime startTime = DateUtil.beginOfDay(nowDate);
            DateTime endTime = DateUtil.endOfQuarter(nowDate);
            String date = DateUtil.format(nowDate, DatePattern.CHINESE_DATE_PATTERN).substring(0, 5);
            int quarter = nowDate.quarter();

            for (SysTaskCycle sysTaskCycle : sysTaskCycleList) {

                Integer frequency = sysTaskCycle.getFrequency();
                List<SysUserPost> sysUserPosts = sysUserPostMapper.selectList(Wrappers.<SysUserPost>lambdaQuery()
                        .eq(SysUserPost::getPostId, sysTaskCycle.getPostId())
                );

                SysTaskPlan sysTaskPlan = null;
                for (Integer i = 0; i < frequency; i++) {
                    sysTaskPlan = SysTaskPlan.builder()
                            .taskName(date + "第" + quarter + "季度" + name)
                            .remarks(CharSequenceUtil.EMPTY)
                            .cycleId(4L)
                            .finish(0)
                            .creatorId(1L)
                            .publishTime(nowDate)
                            .createTime(nowDate)
                            .startTime(startTime)
                            .endTime(endTime)
                            .state(1)
                            .type(1)
                            .taskType(1)
                            .flowpath(2)
                            .build();
                    sysTaskPlanMapper.insert(sysTaskPlan);

                    SysTaskPlanDetail sysTaskPlanDetail = null;
                    for (SysUserPost sysUserPost : sysUserPosts) {
                        sysTaskPlanDetail = new SysTaskPlanDetail();
                        sysTaskPlanDetail.setUserId(sysUserPost.getUserId());
                        sysTaskPlanDetail.setPlanId(sysTaskPlan.getId());
                        sysTaskPlanDetail.setFinish(0);
                        sysTaskPlanDetail.setState(1);
                        sysTaskPlanDetailMapper.insert(sysTaskPlanDetail);
                    }
                    extracted(sysTaskPlan);
                }
            }
        }
        log.info("季度定时结束创建任务计划");
    }

    /*    *//**
     * 半年执行一次0点执行
     *//*
    @Async
    @Scheduled(cron = "1 00 00 1 7,1 ?")
    public void halfYear() {
        log.info("半年定时开始创建任务计划");
        List<SysTaskCycle> sysTaskCycleList = sysTaskCycleService.list(Wrappers.<SysTaskCycle>lambdaQuery()
                .eq(SysTaskCycle::getStatus, 1)
                .eq(SysTaskCycle::getCycleId, 2)
        );
        if (CollUtil.isNotEmpty(sysTaskCycleList)) {

            for (SysTaskCycle sysTaskCycle : sysTaskCycleList) {
                Integer frequency = sysTaskCycle.getFrequency();
                List<SysUserPost> sysUserPosts = sysUserPostMapper.selectList(Wrappers.<SysUserPost>lambdaQuery()
                        .eq(SysUserPost::getPostId, sysTaskCycle.getPostId())
                );
                if (CollUtil.isNotEmpty(sysUserPosts)) {
                    Date nowDate = DateUtils.getNowDate();
                    Date createTime = DateUtil.beginOfDay(nowDate);
                    Date endTime = DateUtil.endOfQuarter(nowDate);
                    sysUserPosts.forEach(v -> {
                        SysUser sysUser = sysUserMapper.selectOne(Wrappers.<SysUser>lambdaQuery()
                                .eq(SysUser::getUserId, v.getUserId())
                                .eq(SysUser::getStatus, 0)
                                .eq(SysUser::getDelFlag, "0")
                        );
                        if (Objects.nonNull(sysUser)) {
                            for (int i = 0; i < frequency; i++) {
                                SysTaskPlan sysTaskPlan = SysTaskPlan.builder()
                                        .executorId(sysUser.getUserId())
                                        .taskName("半年任务")
                                        .remarks("半年任务")
                                        .cycleId(1)
                                        .finish(0)
                                        .createTime(createTime)
                                        .startTime(createTime)
                                        .endTime(endTime)
                                        .state(1)
                                        .type(1)
                                        .taskType(1)
                                        .build();
                                sysTaskPlanMapper.insert(sysTaskPlan);
                            }
                        }
                    });
                }
            }
        }
        log.info("半年定时结束创建任务计划");

    }*/

    /**
     * 每年执行一次0点执行
     */
    public void year() {
        log.info("每年定时开始创建任务计划");
        List<SysTaskCycle> sysTaskCycleList = sysTaskCycleService.list(Wrappers.<SysTaskCycle>lambdaQuery()
                .eq(SysTaskCycle::getStatus, 1)
                .eq(SysTaskCycle::getCycleId, 5)
        );
        if (CollUtil.isNotEmpty(sysTaskCycleList)) {
            DateTime nowDate = DateUtil.date();
            DateTime startTime = DateUtil.beginOfDay(nowDate);
            DateTime endTime = DateUtil.endOfQuarter(nowDate);
            String date = DateUtil.format(nowDate, DatePattern.CHINESE_DATE_PATTERN).substring(0, 5);

            for (SysTaskCycle sysTaskCycle : sysTaskCycleList) {
                Integer frequency = sysTaskCycle.getFrequency();
                List<SysUserPost> sysUserPosts = sysUserPostMapper.selectList(Wrappers.<SysUserPost>lambdaQuery()
                        .eq(SysUserPost::getPostId, sysTaskCycle.getPostId())
                );

                for (Integer i = 0; i < frequency; i++) {
                    SysTaskPlan sysTaskPlan = SysTaskPlan.builder()
                            .taskName(date + name)
                            .remarks(CharSequenceUtil.EMPTY)
                            .cycleId(5L)
                            .finish(0)
                            .creatorId(1L)
                            .publishTime(nowDate)
                            .createTime(nowDate)
                            .startTime(startTime)
                            .endTime(endTime)
                            .state(1)
                            .type(1)
                            .taskType(1)
                            .flowpath(2)
                            .build();
                    sysTaskPlanMapper.insert(sysTaskPlan);

                    SysTaskPlanDetail sysTaskPlanDetail = null;
                    for (SysUserPost sysUserPost : sysUserPosts) {
                        sysTaskPlanDetail = new SysTaskPlanDetail();
                        sysTaskPlanDetail.setUserId(sysUserPost.getUserId());
                        sysTaskPlanDetail.setPlanId(sysTaskPlan.getId());
                        sysTaskPlanDetail.setFinish(0);
                        sysTaskPlanDetail.setState(1);
                        sysTaskPlanDetailMapper.insert(sysTaskPlanDetail);
                    }
                    extracted(sysTaskPlan);
                }
            }
        }
        log.info("每年定时结束创建任务计划");

    }

    private void extracted(SysTaskPlan sysTaskPlan) {
        SysJob job = new SysJob();
        job.setJobId(sysTaskPlan.getId());
        job.setJobName(sysTaskPlan.getTaskName());
        job.setStatus("0");
        job.setMisfirePolicy("1");
        job.setJobGroup("SYSTEM");
        job.setInvokeTarget("ryTask.stopTaskPlan(" + sysTaskPlan.getId() + "L)");
        job.setConcurrent("0");
        job.setCronExpression(CronUtil.getCron(sysTaskPlan.getEndTime()));
        try {
            ScheduleUtils.createScheduleJob(scheduler, job);
        } catch (Exception e) {
            log.error("定时结束任务异常");
        }
    }

    public void stopTaskPlan(Long planId) {
        SysTaskPlan sysTaskPlan = sysTaskPlanMapper.selectById(planId);
        if (ObjectUtil.isNotNull(sysTaskPlan)) {
            DateTime date = DateUtil.date();
            if (date.isAfter(sysTaskPlan.getEndTime())) {
                SysTaskPlan taskPlan = new SysTaskPlan();
                taskPlan.setFlowpath(3);
                sysTaskPlanMapper.update(taskPlan, Wrappers.<SysTaskPlan>lambdaQuery()
                        .eq(SysTaskPlan::getId, planId)
                        .eq(SysTaskPlan::getFlowpath, 2)
                        .eq(SysTaskPlan::getState, 1)
                );
            }
        }
    }

}
